﻿using System;
using System.Collections.Generic;
using TwlPhy;
using Config;

/// <summary>
/// 受击 曲线移动
/// </summary>
public class CurveHitState : BaseState
{
    //贝塞尔曲线绘制移动曲线
    //起点P0为当前位置   结束点P2与P0成对称 轴为P1
    //墙角曲线击退 应该只有高度增加 X轴固定 进行射线检测
    //需要参数 1 击退距离  2 击退高度
    protected float hitBackDis = 2.5f;
    protected float hitHeight = 2f;

    //贝塞尔曲线定义 (1 - t)^2 P0 + 2 t (1 - t) P1 + t^2 P2;
    protected Vector2 dir = Vector2.right;
    protected Vector3 P0 = Vector3.zero;
    protected Vector3 P1 = Vector3.zero;
    protected Vector3 P2 = Vector3.zero;
    protected float t = 0;
    protected float curveTimeScale = 1.8f;//曲线时间的缩放 >1加快  <1变慢  帧标准时间 phy2d取

    public override void onEnter(FSMArgs args = null)
    {
        //计算时间缩放 
        MoveConfig moveConfig = MoveConfig.get(args.cfgId);
        if (moveConfig == null) {
            Logger.logError("没有读取到配置文件MoveConfig.id " + args.cfgId);
            forceToIdle();
            return;
        }
        curveTimeScale = 1 / (moveConfig.airForce* Physics2D.logicFrame);
        t = 0;
        P0 = new Vector3(Agent.DyBox.centerX,Agent.DyBox.centerZ,0);
        //击退方向还是根据攻击者的坐标来确定
        P2.x = P0.x + dir.x * hitBackDis;
        //P2.y = P0.y + dir.y * hitBackDis;//Y击退暂不定义
        //p1取中间  并加上高度
        P1.x = (P0.x + P2.x) * 0.5f;
        P1.y = hitHeight;
    }

    //逻辑帧
    public override void onTick()
    {
        if (t >= 1 && Agent.DyBox.centerZ <= 0)
        {
            //到达 根据当前高度判断是否应该再弹起
            if (P1.y >= reboundHeight)
            {
                int force = Mathf.CeilToInt(P1.y / reboundForce);
                FSMArgs args = new FSMArgs();
                args.cfgId = force;
                Agent.transFsm(FSM_Flag.AirHit, args, true);
            }
            else
            {
                Agent.transFsm(FSM_Flag.LineDown, null, true);
            }
        }
        else {
            //曲线移动
            doCurve();
        }
    }

    //(1 - t)^2 P0 + 2 t (1 - t) P1 + t^2 P2;
    protected void doCurve() {
        t += Physics2D.logicFrame*curveTimeScale;
        t = t > 1 ? 1 : t;
        Vector3 result = (1 - t) * (1 - t) * P0 + 2 * t * (1 - t) * P1 + t * t * P2;
        float dis = 0;
        float dst = Mathf.Abs(result.x - Agent.DyBox.centerX);
        bool isKnock = Physics2D.moveCast(Agent.DyBox, dir, dst, ref dis); 
        Agent.doMove(dis, 0);
        Agent.updatePosHeight(result.y);
    }
}

